#include <stdio.h>
#include <sys/socket.h>
#include <stdlib.h>
#include <string.h>
#include <netinet/in.h>
#include<fcntl.h>
#include <zconf.h>

#define PORT 8080       // 服务器监听端口
#define MAX_QUEUE 5     // 待连接的队列最大数
#define MAX_LEN 1024    // 接收浏览器数据

int main(int argc, char *argv[]){
    int server_socket_fp;   // 服务端socket句柄
    struct sockaddr_in server_addr;   // 地址结构体
    char buff[MAX_LEN];
    int reuse = 1;

    /**
     * 创建socket
     * AF_INET: IPV4网络操作
     * SOCK_STREAM: 使用TCP协议传输数据
     * 0: 自动选择协议
     */
    if ((server_socket_fp = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
        printf("create socket failed");
        exit(EXIT_FAILURE);
    }
    //端口重用时间设置
    setsockopt(server_socket_fp, SOL_SOCKET, SO_REUSEADDR, (const char*)& reuse, sizeof(int));

    /**
     * 将socket与地址绑定
     * bind参数：
     *     socket描述符
     *     地址结构体，需要强转成struct sockaddr类型
     *     结构体长度，传入的是指针，无法再函数内部获取长度
     */
    memset(&server_addr, 0, sizeof(server_addr));
    server_addr.sin_family = AF_INET;
    server_addr.sin_addr.s_addr = htonl(INADDR_ANY);   // INADDR_ANY表示任何地址访问都可以
    server_addr.sin_port = htons(PORT);   // 端口号
    if (bind(server_socket_fp, (struct sockaddr *) &server_addr, sizeof(server_addr)) < 0) {
        printf("bind socket with addr struct failed!");
        exit(EXIT_FAILURE);
    }

    /**
     * 监听链接
     * 参数：
     *     socket描述符
     *     待连接队列的最大个数，一般为5
     */
    listen(server_socket_fp, MAX_QUEUE);

    /**
     * 与客户端建立连接
     * 参数：
     *     socket文件描述符
     *     客户端地址信息的结构体，不关心可以传NULL
     *     客户端地址长度，不关心可以传NULL
     * 返回值：
     *     socket文件描述符，在与客户端建立连接后，accpet还是会生成一个专门用于和当前客户端通信的socket，
     *     而原来那个socket照常负责和其他等待建立连接的客户端建立通信
     */
    int client_socket_fp = accept(server_socket_fp, NULL, NULL);

    /**
     * 读取浏览器的内容
     * 参数：
     *     文件描述符，从哪个文件读，这里填写accept返回的文件句柄
     *     读的内容存到buff中
     *     共读多少个字节
     */
    read(client_socket_fp, buff, MAX_LEN);
    //printf("%s", buff);
    //printf("open file is %s", argv[1]);




    char buf[1024];

    strcpy(buf, "HTTP/1.0 200 OK\r\n");
    send(client_socket_fp, buf, strlen(buf), 0);
    strcpy(buf, "Server: lanfiletranst\r\n");
    send(client_socket_fp, buf, strlen(buf), 0);
    //sprintf(buf, "Content-Type: application/octet-stream; filename=\"test.txt\"\r\n");
    char *getfilename;
    for(getfilename = argv[1]+strlen(argv[1]); getfilename > argv[1]; getfilename--) {
      if(*getfilename == 47) {getfilename++; break;}
    }
    sprintf(buf, "Content-Disposition: attachment; filename=\"%s\"\r\n", getfilename);
    send(client_socket_fp, buf, strlen(buf), 0);
    strcpy(buf, "\r\n");
    send(client_socket_fp, buf, strlen(buf), 0);
    
    int fd=open(argv[1],O_RDONLY);
    int i;
    while((i = read(fd,&buf,sizeof(buf)))>0)
      send(client_socket_fp, buf, i, 0);
    close(fd);

    close(client_socket_fp);
    close(server_socket_fp);
    return 0;
}
